package gatperdut.chato.core.characters;

import gatperdut.chato.constants.CSConstantsLanguages;
import gatperdut.chato.core.ChatoServer;
import gatperdut.chato.core.characters.health.HealthController;
import gatperdut.chato.core.combat.CombatController;
import gatperdut.chato.core.echoes.EchoesController;
import gatperdut.chato.core.interpreter.BaseInterpreter;
import gatperdut.chato.core.item.ItemController;
import gatperdut.chato.core.item.inventory.BoxInventoryController;
import gatperdut.chato.core.item.inventory.EntityInventoryController;
import gatperdut.chato.core.item.inventory.InventoryController;
import gatperdut.chato.core.keywords.KeywordsController;
import gatperdut.chato.core.room.RoomController;
import gatperdut.chato.core.scores.ScoresController;
import gatperdut.chato.core.skills.SkillsController;
import gatperdut.chato.core.threads.CraftThread;
import gatperdut.chato.core.threads.NotifyingThread;
import gatperdut.chato.model.Chato.Constant.Language;
import gatperdut.chato.model.Chato.Entity.Entity;

public abstract class BaseController extends NotifyingThread {

    private BaseInterpreter interpreter;

    private final ChatoServer chatoServer;

    private KeywordsController keywordsController;

    private RoomController roomController;

    private Entity character;

    private final EchoesController echoes = new EchoesController();

    private final CombatController combatController = new CombatController();

    private CraftThread craftThread = null;

    private InventoryController inventoryController;

    private ScoresController scoresController;

    private HealthController healthController;

    private SkillsController skillsController;

    public EntityInventoryController getInventoryController() {
        return (EntityInventoryController) inventoryController;
    }

    public abstract void tx( String message );

    public abstract String rx();

    public void enterRoom( RoomController nextRoomController ) {
        setRoomController( nextRoomController );
        getCharacter().setRoom( nextRoomController.getRoom() );
    }

    public String getCommunicationLanguage() {
        Language l = getCharacter().getCurrentLanguage();
        return CSConstantsLanguages.getLanguageAliases( l ).get( 0 );
    }

    public abstract String whoAmI();

    public boolean hasOneFreeHand() {
        return getInventoryController().hasOneFreeHand();
    }

    public ItemController getLHandItemController() {
        return getInventoryController().getLHandItemController();
    }

    public ItemController getRHandItemController() {
        return getInventoryController().getRHandItemController();
    }

    public void handleSpawnedItem( InventoryController invC, ItemController ic ) {
        if ( invC instanceof BoxInventoryController ) {
            ( (BoxInventoryController) invC ).putInInventory( ic );
        }
        else {
            if ( getInventoryController().hasOneFreeHand() ) {
                getInventoryController().take( ic );
            }
            else {
                tx( "You discard " + ic.getShortDesc( true ) + " at your feet." );
                getRoomController().getInventoryController().putInInventory( ic );
            }
        }
    }

    public void die( BaseController killer ) {
        // --stop combat stuff
        if ( getCombatController().isInCombat() ) {
            if ( getCombatController().isAttacking() ) {
                BaseController target = getCombatController().getTarget();
                getCombatController().setTarget( null );
                target.getCombatController().handleDeadAttacker( this );
            }
            for ( BaseController attacker : getCombatController().getAttackers() ) {
                if ( attacker != killer ) {
                    attacker.getCombatController().handleDeadTarget();
                }
            }
            getCombatController().stopCombatThread();
        }

        if ( isCrafting() ) {
            stopCraftThread();
        }

        getRoomController().getCharactersController().leaveRoom( this );

        // --drop what you are holding
        ItemController l = getLHandItemController();
        if ( l != null ) {
            getInventoryController().takeFromInventory( l );
            getRoomController().getInventoryController().putInInventory( l );
        }
        ItemController r = getRHandItemController();
        if ( r != null ) {
            getInventoryController().takeFromInventory( r );
            getRoomController().getInventoryController().putInInventory( r );
        }

        // --put corpse in room
        ItemController corpse = getChatoServer().getItemHandler().genCorpse( this );
        getRoomController().getInventoryController().putInInventory( corpse );

        getEchoes().txDie();
    }

    public void stopCraftThread() {
        tx( "You stop your craft." );
        getCraftThread().interrupt();
        setCraftThread( null );
    }

    public boolean isCrafting() {
        return getCraftThread() != null;
    }

    public boolean isPacifist() {
        return getCharacter().getSettings().isPacifist();
    }

    public void setPacifist( boolean on ) {
        getCharacter().getSettings().setPacifist( on );
    }

    public boolean isAcceptGive() {
        return getCharacter().getSettings().isAcceptGive();
    }

    public void setAcceptGive( boolean on ) {
        getCharacter().getSettings().setAcceptGive( on );
    }

    public String getQuickStatus() {
        return "[" + getHealthController().getHP() + "]";
    }

    public ChatoServer getChatoServer() {
        return chatoServer;
    }

    public BaseInterpreter getInterpreter() {
        return interpreter;
    }

    public void setInterpreter( BaseInterpreter interpreter ) {
        this.interpreter = interpreter;
    }

    public Entity getCharacter() {
        return character;
    }

    public void setCharacter( Entity character ) {
        this.character = character;
        setKeywordsController( new KeywordsController( character.getKeywords() ) );
    }

    public RoomController getRoomController() {
        return roomController;
    }

    public void setRoomController( RoomController roomController ) {
        this.roomController = roomController;
    }

    public EchoesController getEchoes() {
        return echoes;
    }

    public CraftThread getCraftThread() {
        return craftThread;
    }

    public void setCraftThread( CraftThread craftThread ) {
        this.craftThread = craftThread;
    }

    public KeywordsController getKeywordsController() {
        return keywordsController;
    }

    public void setKeywordsController( KeywordsController keywordsController ) {
        this.keywordsController = keywordsController;
    }

    public void setInventoryController( InventoryController inventoryController ) {
        this.inventoryController = inventoryController;
    }

    public BaseController( ChatoServer chatoServer ) {
        this.chatoServer = chatoServer;
    }

    public CombatController getCombatController() {
        return combatController;
    }

    public ScoresController getScoresController() {
        return scoresController;
    }

    public void setScoresController( ScoresController scoresController ) {
        this.scoresController = scoresController;
    }

    public SkillsController getSkillsController() {
        return skillsController;
    }

    public void setSkillsController( SkillsController skillsController ) {
        this.skillsController = skillsController;
    }

    public HealthController getHealthController() {
        return healthController;
    }

    public void setHealthController( HealthController healthController ) {
        this.healthController = healthController;
    }

}
